import fs from 'node:fs/promises';
import { pathToFileURL } from 'node:url';
import type { ViteDevServer } from 'vite';

interface ServerRenderMiddlewareOptions {
  publicPath: string;
  isProd: boolean;
  templatePath: string;
  entryServerPath: string;
  vite?: ViteDevServer;
}

export function createServerRenderMiddleware(
  options: ServerRenderMiddlewareOptions
) {
  return async function ServerRenderMiddleware(req, res) {
    try {
      const url = req.originalUrl.replace(options.publicPath, '');

      let template: string;
      let render: (
        value: string
      ) => Promise<{ html: string; head?: string; css: string }>;
      if (!options.isProd && options.vite) {
        // Always read fresh template in development
        template = await fs.readFile(options.templatePath, 'utf-8');
        template = await options.vite.transformIndexHtml(url, template);
        render = (await options.vite.ssrLoadModule(options.entryServerPath))
          .render;
      } else {
        template = await fs.readFile(options.templatePath, 'utf-8');
        // 将绝对路径转换为 file:// URL 格式
        const entryServerUrl = pathToFileURL(options.entryServerPath).href;
        render = (await import(entryServerUrl)).render;
      }

      const rendered = await render(url);

      const html = template
        .replace(`<!--app-head-->`, rendered.head ?? '')
        .replace(`<!--css-html-->`, rendered.css ?? '')
        .replace(`<!--app-html-->`, rendered.html ?? '');

      res.status(200).set({ 'Content-Type': 'text/html' }).send(html);
    } catch (e) {
      options.vite?.ssrFixStacktrace(e);
      console.log(e.stack);
      res.status(500).end(e.stack);
    }
  };
}
